package app

import (
	"example.csi-ephemeral/config"
	"example.csi-ephemeral/driver/local"
	"example.csi-ephemeral/version"
	"fmt"
	"github.com/sirupsen/logrus"
	"github.com/spf13/cobra"
	"google.golang.org/grpc"
	"log"
	"net"
	"os"
	"strings"
)

var (
	endpoint       string
	nodeid         string
	logFile        string
	logFileMaxSize int
)

func parseEndpoint(ep string) (string, string, error) {
	if strings.HasPrefix(strings.ToLower(ep), "unix://") || strings.HasPrefix(strings.ToLower(ep), "tcp://") {
		s := strings.SplitN(ep, "://", 2)
		if s[1] != "" {
			return s[0], s[1], nil
		}
	}
	return "", "", fmt.Errorf("Invalid endpoint: %v", ep)
}

func NewCommand() *cobra.Command {
	rootCmd := &cobra.Command{
		Use: "csi-custom-local",
		Run: func(cmd *cobra.Command, args []string) {
			// init config
			config.InitConfig(endpoint, nodeid)

			logrus.SetLevel(logrus.InfoLevel)

			proto, addr, err := parseEndpoint(endpoint)
			if err != nil {
				log.Fatalf("Failed to parse %s: %v", endpoint, err)
			}

			if proto == "unix" {
				if err := os.Remove(addr); err != nil && !os.IsNotExist(err) {
					log.Fatalf("Failed to remove %s, error: %s", addr, err.Error())
				}
			}
			
			lis, err := net.Listen(proto, addr)
			if err != nil {
				log.Fatalf("Failed to listen on %s: %v", endpoint, err)
			}

			s := grpc.NewServer()
			csiServer := local.NewServer()
			csiServer.RegisterIdentityServer(s)
			csiServer.RegisterControllerServer(s)
			csiServer.RegisterNodeServer(s)

			log.Printf("Starting CSI driver on %s", endpoint)
			if err := s.Serve(lis); err != nil {
				log.Fatalf("Failed to serve: %v", err)
			}
		},
	}
	versionCmd := &cobra.Command{
		Use:   "version",
		Short: "Print the version info.",
		Run: func(cmd *cobra.Command, args []string) {
			fmt.Print(version.String())
		},
	}

	rootCmd.AddCommand(versionCmd)
	rootCmd.PersistentFlags().StringVarP(&endpoint, "endpoint", "", "unix://plugin/csi.sock", "CSI endpoint")
	rootCmd.PersistentFlags().StringVarP(&nodeid, "nodeid", "", "", "node ID")
	return rootCmd
}
